from fastapi import APIRouter, Request, Form, status, Query, Body
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.exceptions import RequestValidationError
from starlette.templating import Jinja2Templates
from models import COLLECTION_NAMES
from models.db import get_mongo_db, get_redis_client
from models.models import AISupplierModel, AIRoleModel
from schemas import User, Supplier, AIRole, Consultation
from utils.response import Response
from utils.password_encryption import password_hash, verify_password
from bson import ObjectId
import json
from typing import List, Optional
from datetime import datetime

router = APIRouter(prefix="/api/admin", tags=["管理员"])
templates = Jinja2Templates(directory="templates")


@router.get("/users")
async def get_users(request: Request, page: int = Query(1, ge=1), limit: int = Query(10, ge=1, le=100)):
    """获取用户列表"""
    skip = (page - 1) * limit

    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 查询用户总数
    total = mongo_db[COLLECTION_NAMES["users"]].count_documents({})

    # 查询用户列表
    users = list(
        mongo_db[COLLECTION_NAMES["users"]]
        .find()
        .skip(skip)
        .limit(limit)
        .sort("created_at", -1)
    )

    # 转换为可序列化的格式
    data = []
    for user in users:
        # 统计用户的问诊数量
        consultation_count = mongo_db[COLLECTION_NAMES["consultations"]].count_documents({"user_id": user["_id"]})

        # 确保created_at是datetime对象
        created_at = user["created_at"]
        if isinstance(created_at, str):
            # 如果是字符串，尝试解析为datetime对象
            try:
                from datetime import datetime
                created_at = datetime.fromisoformat(created_at.replace('Z', '+00:00'))
            except:
                # 如果解析失败，使用当前时间
                from datetime import datetime
                created_at = datetime.utcnow()
        
        data.append({
            "id": str(user["_id"]),
            "username": user["username"],
            "email": user["email"],
            "phone": user.get("phone", ""),
            "is_admin": user.get("is_admin", False),
            "consultation_count": consultation_count,
            "created_at": created_at.isoformat() if hasattr(created_at, 'isoformat') else str(created_at)
        })

    return Response.success(
        data={
            "items": data,
            "total": total,
            "page": page,
            "limit": limit,
            "pages": (total + limit - 1) // limit
        }
    )


@router.put("/users/{user_id}")
async def update_user(
        request: Request,
        user_id: str,
        username: str = Body(...),
        email: str = Body(...),
        phone: Optional[str] = Body(None),
        is_admin: bool = Body(False)
):
    """更新用户信息"""
    # 避免修改当前登录的管理员权限
    current_user = request.state.user
    if str(current_user["_id"]) == user_id and not is_admin:
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="不能取消自己的管理员权限"
        )

    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 更新用户信息
    result = mongo_db[COLLECTION_NAMES["users"]].update_one(
        {"_id": ObjectId(user_id)},
        {
            "$set": {
                "username": username,
                "email": email,
                "phone": phone,
                "is_admin": is_admin
            }
        }
    )

    if result.matched_count == 0:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="用户不存在"
        )

    return Response.success(message="更新成功")


@router.delete("/users/{user_id}")
async def delete_user(request: Request, user_id: str):
    """删除用户"""
    # 不允许删除自己
    if str(request.state.user["_id"]) == user_id:
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="不能删除自己的账户"
        )

    # 获取数据库连接实例
    mongo_db = get_mongo_db()
    redis_client = get_redis_client()

    # 开始事务（在MongoDB中模拟）
    # 1. 删除用户的所有问诊会话
    consultations = list(
        mongo_db[COLLECTION_NAMES["consultations"]].find({"user_id": ObjectId(user_id)})
    )

    # 删除Redis中的对话记录
    for consultation in consultations:
        redis_key = f"consultation:{str(consultation['_id'])}"
        redis_client.delete(redis_key)

    # 删除数据库中的问诊记录
    mongo_db[COLLECTION_NAMES["consultations"]].delete_many({"user_id": ObjectId(user_id)})

    # 2. 删除用户
    result = mongo_db[COLLECTION_NAMES["users"]].delete_one({"_id": ObjectId(user_id)})

    if result.deleted_count == 0:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="用户不存在"
        )

    return Response.success(message="删除成功")


# AI供应商管理

@router.get("/suppliers")
async def get_suppliers(request: Request):
    """获取AI供应商列表"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    suppliers = list(
        mongo_db[COLLECTION_NAMES["ai_suppliers"]]
        .find()
        .sort("created_at", 1)
    )

    # 转换为可序列化的格式
    data = []
    for supplier in suppliers:
        # 统计使用该供应商的角色数量
        role_count = mongo_db[COLLECTION_NAMES["ai_roles"]].count_documents({"supplier_id": supplier["_id"]})

        # 确保created_at是datetime对象
        created_at = supplier["created_at"]
        if isinstance(created_at, str):
            # 如果是字符串，尝试解析为datetime对象
            try:
                from datetime import datetime
                created_at = datetime.fromisoformat(created_at.replace('Z', '+00:00'))
            except:
                # 如果解析失败，使用当前时间
                from datetime import datetime
                created_at = datetime.utcnow()

        data.append({
            "id": str(supplier["_id"]),
            "name": supplier["name"],
            "api_key": supplier["api_key"],
            "api_url": supplier["api_url"],
            "description": supplier.get("description", ""),
            "is_active": supplier.get("is_active", True),
            "role_count": role_count,
            "created_at": created_at.isoformat() if hasattr(created_at, 'isoformat') else str(created_at)
        })

    return Response.success(data=data)


@router.post("/suppliers")
async def create_supplier(
        request: Request,
        name: str = Body(...),
        api_key: str = Body(...),
        api_url: str = Body(...),
        description: Optional[str] = Body(None),
        is_active: bool = Body(True)
):
    """创建AI供应商"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 检查名称是否已存在
    if mongo_db[COLLECTION_NAMES["ai_suppliers"]].find_one({"name": name}):
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="供应商名称已存在"
        )

    # 创建供应商
    supplier = AISupplierModel(
        name=name,
        api_key=api_key,
        api_url=api_url,
        description=description,
        is_active=is_active
    )

    # 保存到数据库
    result = mongo_db[COLLECTION_NAMES["ai_suppliers"]].insert_one(supplier.to_dict())

    return Response.success(
        message="创建成功",
        data={"id": str(result.inserted_id)}
    )


@router.put("/suppliers/{supplier_id}")
async def update_supplier(
        request: Request,
        supplier_id: str,
        name: str = Body(...),
        api_key: str = Body(...),
        api_url: str = Body(...),
        description: Optional[str] = Body(None),
        is_active: bool = Body(True)
):
    """更新AI供应商"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 检查名称是否被其他供应商使用
    existing = mongo_db[COLLECTION_NAMES["ai_suppliers"]].find_one({
        "name": name,
        "_id": {"$ne": ObjectId(supplier_id)}
    })
    if existing:
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="供应商名称已存在"
        )

    # 更新供应商
    result = mongo_db[COLLECTION_NAMES["ai_suppliers"]].update_one(
        {"_id": ObjectId(supplier_id)},
        {
            "$set": {
                "name": name,
                "api_key": api_key,
                "api_url": api_url,
                "description": description,
                "is_active": is_active
            }
        }
    )

    if result.matched_count == 0:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="供应商不存在"
        )

    # 如果禁用了供应商，同时禁用使用该供应商的所有角色
    if not is_active:
        mongo_db[COLLECTION_NAMES["ai_roles"]].update_many(
            {"supplier_id": ObjectId(supplier_id)},
            {"$set": {"is_active": False}}
        )

    return Response.success(message="更新成功")


@router.delete("/suppliers/{supplier_id}")
async def delete_supplier(request: Request, supplier_id: str):
    """删除AI供应商"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 检查是否有角色使用该供应商
    role_count = mongo_db[COLLECTION_NAMES["ai_roles"]].count_documents({"supplier_id": ObjectId(supplier_id)})
    if role_count > 0:
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message=f"该供应商被{role_count}个角色使用，无法删除"
        )

    # 删除供应商
    result = mongo_db[COLLECTION_NAMES["ai_suppliers"]].delete_one({"_id": ObjectId(supplier_id)})

    if result.deleted_count == 0:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="供应商不存在"
        )

    return Response.success(message="删除成功")


# AI角色管理

@router.get("/roles")
async def get_roles(request: Request):
    """获取AI角色列表"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    roles = list(
        mongo_db[COLLECTION_NAMES["ai_roles"]]
        .find()
        .sort("created_at", 1)
    )

    # 转换为可序列化的格式
    data = []
    for role in roles:
        # 获取供应商信息
        supplier = mongo_db[COLLECTION_NAMES["ai_suppliers"]].find_one({"_id": role["supplier_id"]})

        # 确保created_at是datetime对象
        created_at = role["created_at"]
        if isinstance(created_at, str):
            # 如果是字符串，尝试解析为datetime对象
            try:
                from datetime import datetime
                created_at = datetime.fromisoformat(created_at.replace('Z', '+00:00'))
            except:
                # 如果解析失败，使用当前时间
                from datetime import datetime
                created_at = datetime.utcnow()

        data.append({
            "id": str(role["_id"]),
            "name": role["name"],
            "supplier_id": str(role["supplier_id"]),
            "supplier_name": supplier["name"] if supplier else "未知",
            "description": role.get("description", ""),
            "system_prompt": role.get("prompt", ""),  # 添加系统提示词
            "avatar": role.get("avatar", None),
            "is_active": role.get("is_active", True),
            "model": role.get("model", None),  # 添加模型名称
            "temperature": role.get("temperature", 0.7),  # 添加温度参数
            "max_tokens": role.get("max_tokens", 1000),  # 添加最大token数
            "status": role.get("status", "active"),  # 添加状态
            "is_default": role.get("is_default", False),  # 添加是否默认
            "created_at": created_at.isoformat() if hasattr(created_at, 'isoformat') else str(created_at)
        })

    return Response.success(data=data)


@router.post("/roles")
async def create_role(
        request: Request,
        name: str = Body(...),
        system_prompt: str = Body(..., alias="system_prompt"),
        supplier_id: str = Body(...),
        description: Optional[str] = Body(None),
        avatar: Optional[str] = Body(None),
        is_active: bool = Body(True),
        model: Optional[str] = Body(None),
        temperature: Optional[float] = Body(None),
        max_tokens: Optional[int] = Body(None),
        role_status: Optional[str] = Body(None, alias="status"),
        is_default: Optional[bool] = Body(None)
):
    """创建AI角色"""
    # 打印请求体用于调试
    print(f"Received request body: {await request.body()}")
    
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 验证供应商是否存在
    supplier = mongo_db[COLLECTION_NAMES["ai_suppliers"]].find_one({"_id": ObjectId(supplier_id)})
    if not supplier:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="选择的供应商不存在"
        )

    # 如果供应商未激活，不允许创建角色
    if not supplier.get("is_active", False):
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="选择的供应商未激活"
        )

    # 检查角色名称是否已存在
    if mongo_db[COLLECTION_NAMES["ai_roles"]].find_one({"name": name}):
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="角色名称已存在"
        )

    # 创建角色
    role = AIRoleModel(
        name=name,
        prompt=system_prompt,
        supplier_id=ObjectId(supplier_id),
        description=description,
        avatar=avatar,
        is_active=is_active,
        model=model,
        temperature=temperature,
        max_tokens=max_tokens,
        role_status=role_status,
        is_default=is_default
    )

    # 保存到数据库
    result = mongo_db[COLLECTION_NAMES["ai_roles"]].insert_one(role.to_dict())

    return Response.success(
        message="创建成功",
        data={"id": str(result.inserted_id)}
    )


@router.put("/roles/{role_id}")
async def update_role(
        request: Request,
        role_id: str,
        name: str = Body(...),
        system_prompt: str = Body(..., alias="system_prompt"),
        supplier_id: str = Body(...),
        description: Optional[str] = Body(None),
        avatar: Optional[str] = Body(None),
        is_active: bool = Body(True),
        model: Optional[str] = Body(None),
        temperature: Optional[float] = Body(None),
        max_tokens: Optional[int] = Body(None),
        role_status: Optional[str] = Body(None, alias="status"),
        is_default: Optional[bool] = Body(None)
):
    """更新AI角色"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()
    
    # 验证供应商是否存在
    supplier = mongo_db[COLLECTION_NAMES["ai_suppliers"]].find_one({"_id": ObjectId(supplier_id)})
    if not supplier:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="选择的供应商不存在"
        )

    # 如果供应商未激活，不允许将角色设置为激活状态
    if is_active and not supplier.get("is_active", False):
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="选择的供应商未激活，无法激活角色"
        )

    # 检查角色名称是否被其他角色使用
    existing = mongo_db[COLLECTION_NAMES["ai_roles"]].find_one({
        "name": name,
        "_id": {"$ne": ObjectId(role_id)}
    })
    if existing:
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message="角色名称已存在"
        )

    # 更新角色
    result = mongo_db[COLLECTION_NAMES["ai_roles"]].update_one(
        {"_id": ObjectId(role_id)},
        {
            "$set": {
                "name": name,
                "prompt": system_prompt,
                "supplier_id": ObjectId(supplier_id),
                "description": description,
                "avatar": avatar,
                "is_active": is_active,
                "model": model,
                "temperature": temperature,
                "max_tokens": max_tokens,
                "role_status": role_status,
                "is_default": is_default
            }
        }
    )

    if result.matched_count == 0:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="角色不存在"
        )

    return Response.success(message="更新成功")


@router.delete("/roles/{role_id}")
async def delete_role(request: Request, role_id: str):
    """删除AI角色"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    # 检查是否有问诊会话使用该角色
    consultation_count = mongo_db[COLLECTION_NAMES["consultations"]].count_documents({"role_id": ObjectId(role_id)})
    if consultation_count > 0:
        return Response.error(
            code=status.HTTP_400_BAD_REQUEST,
            message=f"该角色被{consultation_count}个问诊会话使用，无法删除"
        )

    # 删除角色
    result = mongo_db[COLLECTION_NAMES["ai_roles"]].delete_one({"_id": ObjectId(role_id)})

    if result.deleted_count == 0:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="角色不存在"
        )

    return Response.success(message="删除成功")


# 问诊记录管理
@router.get("/consultations")
async def get_all_consultations(request: Request, page: int = Query(1, ge=1), limit: int = Query(10, ge=1, le=100)):
    """获取所有问诊记录（管理员）"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()

    skip = (page - 1) * limit

    # 查询总数
    total = mongo_db[COLLECTION_NAMES["consultations"]].count_documents({})

    # 查询问诊记录
    consultations = list(
        mongo_db[COLLECTION_NAMES["consultations"]]
        .find()
        .skip(skip)
        .limit(limit)
        .sort("updated_at", -1)
    )

    # 转换为可序列化的格式
    data = []
    for consultation in consultations:
        # 获取用户信息
        user = mongo_db[COLLECTION_NAMES["users"]].find_one({"_id": consultation["user_id"]})
        # 获取角色信息
        role = mongo_db[COLLECTION_NAMES["ai_roles"]].find_one({"_id": consultation["role_id"]})

        data.append({
            "id": str(consultation["_id"]),
            "user_id": str(consultation["user_id"]),
            "username": user["username"] if user else "未知",
            "title": consultation["title"],
            "role_id": str(consultation["role_id"]),
            "role_name": role["name"] if role else "未知",
            "status": consultation["status"],
            "created_at": consultation["created_at"].isoformat(),
            "updated_at": consultation["updated_at"].isoformat()
        })

    return Response.success(
        data={
            "items": data,
            "total": total,
            "page": page,
            "limit": limit,
            "pages": (total + limit - 1) // limit
        }
    )


@router.get("/consultations/{consultation_id}/messages")
async def get_consultation_messages_admin(request: Request, consultation_id: str):
    """获取问诊会话的消息列表（管理员）"""
    # 获取数据库连接实例
    mongo_db = get_mongo_db()
    redis_client = get_redis_client()

    # 验证问诊是否存在
    consultation = mongo_db[COLLECTION_NAMES["consultations"]].find_one({"_id": ObjectId(consultation_id)})

    if not consultation:
        return Response.error(
            code=status.HTTP_404_NOT_FOUND,
            message="问诊会话不存在"
        )

    # 从Redis获取消息记录
    redis_key = f"consultation:{consultation_id}"
    # 使用类型检查来处理可能的异步返回值
    messages = redis_client.lrange(redis_key, 0, -1)
    
    # 转换消息格式
    result = []
    try:
        # 处理可能的异步对象
        if hasattr(messages, '__await__'):
            # 如果是awaitable对象，我们需要await它
            # 但由于这是在同步函数中，我们只能尝试直接使用
            message_list = [messages] if messages else []
        elif isinstance(messages, (list, tuple)):
            message_list = list(messages)
        else:
            # 其他情况，尝试转换为列表
            message_list = [messages] if messages else []

        # 反转列表以获得正确的顺序
        for msg_str in reversed(message_list):  # 倒序，使最早的消息在前
            try:
                if isinstance(msg_str, str):
                    msg = json.loads(msg_str)
                    result.append({
                        "role": msg["role"],
                        "content": msg["content"],
                        "timestamp": msg["timestamp"]
                    })
            except:
                continue
    except Exception as e:
        # 忽略处理错误
        pass

    return Response.success(data=result)
